package com.wondertek.poms.pre.manager.imageback;

import java.util.ArrayList;
import java.util.List;

import cn.hutool.core.bean.BeanUtil;
import com.wondertek.poms.pre.vo.ProductInfoPackageLogVo;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.wondertek.poms.common.constant.Constants;
import com.wondertek.poms.common.exception.BusinessException;
import com.wondertek.poms.common.exception.MessageCodes;
import com.wondertek.poms.core.config.RedisDistributedLock;
import com.wondertek.poms.core.service.IContentService;
import com.wondertek.poms.core.service.IProductInfoPackageService;
import com.wondertek.poms.core.service.ISyncTaskService;
import com.wondertek.poms.dao.po.Content;
import com.wondertek.poms.dao.po.ProductInfoPackage;
import com.wondertek.poms.dao.po.SyncTask;
import com.wondertek.poms.dao.transVo.TransferMessageVo;
import com.wondertek.poms.pre.manager.filter.ProductInfoRuleManager;
import com.wondertek.poms.pre.utils.callback.SourceUtil;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class RulePassProcess {

	@Autowired
    private IProductInfoPackageService productInfoPackageService;
    @Autowired
    private ProductInfoRuleManager ruleManager;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private RedisDistributedLock lock;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private IContentService contentService;
    @Autowired
    SourceUtil sourceUtil;
    @Autowired
    private ISyncTaskService syncTaskService;

    @Async(value = "passRulePool")
    public void process(String message) {
		Boolean isSuccess = true;
		SyncTask st = JSON.parseObject(message, SyncTask.class);
		
		try {
			mainProcess(st);
		} catch (Exception e) {
			log.error("内容同步主流程|处理异常：", e);
			isSuccess = false;
			
			if (st != null) {
                st.setStatus(3);
                syncTaskService.save(st);
            }
		} finally {
			callback(st, isSuccess);
		}
    }
    
    @Async(value = "passRulePool")
    public void process(SyncTask st) {
		Boolean isSuccess = true;
		try {
			mainProcess(st);
		} catch (Exception e) {
			log.error(st.getContentId() + "内容同步主流程|处理异常：", e);
			isSuccess = false;
			
			st.setStatus(3);
            syncTaskService.save(st);
		} finally {
			callback(st, isSuccess);
		}
    }
    
    private void callback(SyncTask st, boolean isSuccess) {
    	log.info("内容同步主流程|业务数据：" + st.getContentId() + "媒资id：" + st.getAssetId() + "同步是否成功：" + isSuccess);
    	if (!isSuccess) {
	    	try {
				// 删除同步锁以及去重key
				if (st.getAssetId() != null) {
					String requestId = redisTemplate.opsForValue().get(Constants.SYNC_LOCK_REQUESTID + st.getAssetId());
					log.info("key:" + Constants.SYNC_LOCK_REQUESTID + st.getAssetId() + "|value:" + requestId + "|contentId:" + st.getContentId());
					if (requestId != null) {
						// 1.解锁
				        boolean result = lock.unLock(Constants.SYNC_LOCK_PREFIX + st.getAssetId(), requestId);
						log.info("redis 释放锁==>" + Constants.SYNC_LOCK_PREFIX + st.getAssetId() + ":" + requestId
								+ " result:" + result + "|contentId:" + st.getContentId());
						// 2.删key
				        String key = st.getContentId() + Constants.REDIS_KEY_SPLIT
				                + st.getOprCode()
				                + Constants.REDIS_KEY_SPLIT
				                + st.getUpdateFields();
				        String md5Key = SecureUtil.md5(key);
				        boolean del = redisTemplate.delete(md5Key);
			            log.info("redis 删除去重key==>" + md5Key + " result:" + del + "|contentId:" + st.getContentId());
						// 3.删本身
			            del = redisTemplate.delete(Constants.SYNC_LOCK_REQUESTID + st.getAssetId());
			            log.info("redis 删除Requestid key==>" + Constants.SYNC_LOCK_REQUESTID + st.getAssetId() + " result:" + del + "|contentId:" + st.getContentId());
					}
				}
			} catch(Exception e) {
				log.error("解锁出错：", e);
			}
	    	sourceUtil.pomsResponse(st, isSuccess);
    	}
	}

    /**
     * 根据内容对象和二级产品规则过滤二级产品
     * @param st
     * @throws Exception
     */
    public void mainProcess(SyncTask st) throws Exception {
		Content c = contentService.findByContentId(st.getContentId());
		if (st.getSuccess()) {
			List<ProductInfoPackage> list = productInfoPackageService.getAllPomsProductInfoPackage();
			List<ProductInfoPackage> productInfoPackageList = new ArrayList<>();
			List<ProductInfoPackageLogVo> productInfoPackageLogVos=new ArrayList<>();
			for (ProductInfoPackage info : list) {
				Boolean needOnline = true;
				// 直播子集 子集 两种媒资类型不用走二级产品规则
				if (!Constants.ASSET_FORM_TYPE_7.equals(c.getFormType()) 
						&& !Constants.ASSET_FORM_TYPE_13.equals(c.getFormType())
						&& !st.getOprCode().equals(Constants.SYNC_POMS_OPRCODE_CONTENT_DELETE)) {
					needOnline = ruleManager.passProductRule(c, info.getProductInfoPackageId());
				}
				info.setOnline(needOnline);
				productInfoPackageList.add(info);
				ProductInfoPackageLogVo vo=new ProductInfoPackageLogVo();
				BeanUtil.copyProperties(info,vo);
				productInfoPackageLogVos.add(vo);
			}
			log.info("二级产品规则|业务数据：" + st.getContentId() + "|媒资id：" + st.getAccessId() + "|二级产品规则过滤结果：" + productInfoPackageLogVos);

			TransferMessageVo vo = new TransferMessageVo();
			vo.setSyncTask(st);
			vo.setProductInfoPackages(productInfoPackageList);
			String jsonStr = JSONUtil.toJsonStr(vo);
			amqpTemplate.convertAndSend(Constants.QUEUE_NEW_POMS_SYNC, jsonStr);
			log.info("二级产品规则|业务数据：" + st.getContentId() + "|媒资id：" + st.getAccessId() + "|发送消息：" + Constants.QUEUE_NEW_POMS_SYNC + "|body:" + jsonStr);
		} else {
			throw new BusinessException(MessageCodes.M980909);
		}
    }

}
